#include <nds.h>
#include <fat.h> 
#include <nds/arm9/console.h> //basic print funcionality
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILE_NAME_LENGTH 100
#define MAX_FIG_NAME_LENGTH 50
#define MAX_POINTS_PER_FIG 600

typedef struct {
	int x;
	int y;
}Coord;

static Coord* coordList;
static char* storeDir = "/CoordCapture/";
static char* figTypesFile = "FigList.txt";
static char** figList;
static uint16* countFig;
static uint16 nbFig=0;
static uint16 activeFig=0;
static uint16 countPoints=0;
static bool didTouch=false;

void paintDownScreenBlack(){
	int i;
	for(i = 0; i < 256 * 192; i++){
		VRAM_A[i] = RGB15(0,0,0);
	}
}

void paintUpScreenBlack(){
	consoleClear();
}

void resetMeasure(){
	countPoints=0;
	didTouch=false;
}

bool readFigType(){
	int i;
	char* figListPath = malloc(MAX_FILE_NAME_LENGTH*sizeof(char));
	figListPath = strcpy(figListPath, storeDir);
	figListPath = strcat(figListPath, figTypesFile);
	if(figListPath==NULL){
		free(figListPath);
		return false;
	}
	printf("reading figure list in : %s \n", figListPath);
	FILE* figListFile = fopen(figListPath, "rb");
	free(figListPath);
	if(figListFile!=NULL){
		//we count how many lines are in the file
		nbFig = 0;
		char* figName = malloc(MAX_FIG_NAME_LENGTH*sizeof(char));
		while(fgets(figName, MAX_FIG_NAME_LENGTH, figListFile)!=NULL){
			nbFig++;
		}
		free(figName);
	}
	if(nbFig==0 || figListFile==NULL){
		printf("no figures in list, creating default\n");
		nbFig=1;
		figList = malloc(sizeof(char*));
		figList[0] = "default";
		countFig = malloc(sizeof(uint16));
		countFig[0] = 0;
	}else{
		//we copy the figure names
		//go back to the beginning of the file
		rewind(figListFile);
		figList = malloc(nbFig*sizeof(char*));
		countFig = malloc(nbFig*sizeof(uint16));
		memset(countFig, 0, nbFig*sizeof(uint16));
		for(i=0; i<nbFig; i++){
			figList[i] = malloc(MAX_FIG_NAME_LENGTH*sizeof(char));
			memset(figList[i], 0, MAX_FIG_NAME_LENGTH*sizeof(char));
			char* fgetsResult = fgets(figList[i], MAX_FIG_NAME_LENGTH, figListFile);
			if(fgetsResult == NULL){
				printf("fgets FAILED\n");
			}else{
				int lg = strlen(figList[i]);
				int j;
				for(j=lg-1; j>=0 && (figList[i][j]==13 || figList[i][j]==10); j--){
					figList[i][j]=0;
				}
			}
		}
	}
	if(figListFile!=NULL){
		fclose(figListFile);
	}
	printf("%u figures, figure types :\n", nbFig);
	for(i=0; i<nbFig; i++){
		printf("%s\n", figList[i]);
	}
	printf("press A to continue\n");
	bool wait = true;
	while(wait){
		scanKeys();
		if(keysDown() & KEY_A){
			wait = false;
		}
		swiWaitForVBlank();
	}
	return true;
}

void selectFigure(){
	paintUpScreenBlack();
	bool selected = false;
	bool changed = false;
	while(!selected){
		printf("current figure type is : %s\npress A to valid, B to change\n",figList[activeFig]);
		changed=false;
		while(!changed && !selected){
			scanKeys();
			if(keysDown() & KEY_A){
				selected = true;
			}else if(keysDown() & KEY_B){
				changed = true;
				activeFig = (activeFig+1)%nbFig;
				paintUpScreenBlack();
			}
			swiWaitForVBlank();
		}
	}
	printf("current figure type now : %s\npress SELECT when you need to change again\n", figList[activeFig]);
}

char* genFileName(){
	char* savePath = malloc(MAX_FILE_NAME_LENGTH*sizeof(char));
	memset(savePath, 0, MAX_FILE_NAME_LENGTH*sizeof(char));
	savePath = strcpy(savePath, storeDir);
	savePath = strcat(savePath, figList[activeFig]);
	char* fileName = malloc(20*sizeof(char));
	memset(fileName, 0, 20*sizeof(char));
	sprintf(fileName, "%u.txt", countFig[activeFig]);
	return strcat(savePath, fileName);
}

void saveFig(){
	paintUpScreenBlack();
	printf("press A to save this figure as %s B to cancel\n",figList[activeFig]);
	bool selected = false;
	while(!selected){
		scanKeys();
		if(keysDown() & KEY_A){
			selected = true;
			//we check that the file does not exist, if it does we go to the next int
			char* savePath;
			FILE* saveFile = NULL;
			do{
				savePath = genFileName();
				saveFile = fopen(savePath, "rb");
				if(saveFile != NULL){
					fclose(saveFile);
					countFig[activeFig]++;
					free(savePath);
				}
			}while(saveFile != NULL);
			saveFile = fopen(savePath, "w");
			if(saveFile != NULL){
				int i;
				for(i = 0; i<countPoints; i++){
					fprintf(saveFile, "%d %d\n", coordList[i].x, coordList[i].y);
				}
				printf("figure saved to %s\n", savePath);
				fclose(saveFile);
				countFig[activeFig]++;
			}else{
				printf("error, figure NOT saved");
			}
			free(savePath);
			
		}else if(keysDown() & KEY_B){
			selected = true;
			printf("figure NOT saved\n");
		}
		swiWaitForVBlank();
	}
}

int main(){
	touchPosition touch;
	consoleDemoInit();
	irqInit();
	irqEnable(IRQ_VBLANK);
	videoSetMode(MODE_FB0);
	vramSetBankA(VRAM_A_LCD);
	//notice we make sure the main graphics engine renders
	//to the lower lcd screen as it would be hard to draw if the 
	//pixels did not show up directly benieth the pen
	lcdMainOnBottom();
	paintDownScreenBlack();
	resetMeasure();
	coordList = malloc(MAX_POINTS_PER_FIG*sizeof(Coord));
	if(fatInitDefault()){
		if(readFigType()){
			selectFigure();
			while(1){
				scanKeys();
				if(keysHeld() & KEY_TOUCH){
					didTouch=true;
					if(countPoints<MAX_POINTS_PER_FIG){
						//read the touchscreen coordinates
						touch=touchReadXY();
						//save point
						coordList[countPoints].x=touch.px;
						coordList[countPoints].y=touch.py;
						//diplay point
						VRAM_A[touch.px + touch.py * 256] = RGB15(31,31,31);
						countPoints++;
					}
				}else{
					if(didTouch){
						saveFig();
						paintDownScreenBlack();
						resetMeasure();
					}
					if(keysDown() & KEY_SELECT){
						selectFigure();
					}
				}
				swiWaitForVBlank();
			}
		}else{
			printf("creating fig list failed\n");
		}
	}else{
		printf("fat init failed\n");
	}
	free(coordList);
	int i;
	for(i = 0; i<nbFig; i++){
		free(figList[i]);
	}
	free(figList);
	free(countFig);
	return 0;
}

